package com.aizuda.easyManagerTool.config;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.type.*;
import org.springframework.beans.factory.annotation.Value;

import java.io.IOException;
import java.sql.*;

@Slf4j
@MappedTypes({String.class})
public class CiphertextTypeHandler extends BaseTypeHandler<String> {


    /**
     * 从 ResultSet 对象中获取指定列名的可空结果。
     * @param rs 是 ResultSet 对象。
     * @param columnName 是列名。
     * @return
     * @throws SQLException
     */
    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String string = rs.getString(columnName);
        if(StrUtil.isEmpty(string)){
            return string;
        }
        try{
            string = CiphertextTypeHandler.decrypt(string);
        }catch (Exception e){

        }
        return string;
    }
    /**
     * 从 ResultSet 对象中获取指定列索引的可空结果。
     * @param rs 是 ResultSet 对象。
     * @param columnIndex  是列的索引。
     * @return
     * @throws SQLException
     */
    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String string = rs.getString(columnIndex);
        if(StrUtil.isEmpty(string)){
            return string;
        }
        return CiphertextTypeHandler.decrypt(string);
    }

    /**
     * 从 CallableStatement 对象中获取指定列索引的可空结果。
     * @param cs CallableStatement 对象。
     * @param columnIndex 是列的索引。
     * @return
     * @throws SQLException
     */
    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String string = cs.getString(columnIndex);
        if(StrUtil.isEmpty(string)){
            return string;
        }
        return CiphertextTypeHandler.decrypt(string);
    }
    /**
     * PreparedStatement 当对一个表进行 insert，会对这张表所有字段执行
     * @param ps 是 PreparedStatement 对象。
     * @param i 是参数的位置。
     * @param parameter 是要设置的参数值。
     * @param jdbcType  是 JDBC 类型。
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        if(StrUtil.isEmpty(parameter)){
            ps.setString(i, parameter);
            return;
        }
        ps.setString(i, CiphertextTypeHandler.encrypt(parameter));
    }


    private static String key = "EasyManagerTool1";

    /**
     * 加密
     * @param value
     * @return
     */
    public static String encrypt(String value){
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key.getBytes());
        return aes.encryptHex(value);
    }

    /**
     * 解密
     * @param value
     * @return
     */
    public static String decrypt(String value){
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key.getBytes());
        return aes.decryptStr(value, CharsetUtil.CHARSET_UTF_8);
    }

}
